package dev.marsh.hunter

import android.app.ActivityManager
import android.app.Notification
import android.app.Service
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Process
import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification
import android.util.Log
import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
import jxl.CellView
import jxl.Workbook
import jxl.write.Label
import jxl.write.WritableWorkbook
import java.io.File
import java.text.SimpleDateFormat
import java.util.*

/**
 * Collect notification service
 *
 * @author zhaozhe
 * Created on 2018/7/14.
 */
class HunterService : NotificationListenerService() {
    private val mFormat = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault())
    private val mFileFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())

    override fun onCreate() {
        super.onCreate()
        if (!checkSettings(this)) {
            goSettings(this)
        }
        ensureServiceRunning()
    }

    private fun ensureServiceRunning() {
        val cn = ComponentName(this, HunterService::class.java)
        val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        var running = false
        val runningServices = activityManager.getRunningServices(Integer.MAX_VALUE)
        runningServices?.let {
            for (runningServiceInfo in it) {
                if (runningServiceInfo.service == cn && runningServiceInfo.pid == Process.myPid()) {
                    running = true
                }
            }
        }
        if (running) {
            if (BuildConfig.DEBUG) {
                Log.e(TAG, "service running")
            }
            return
        }
        toggleService()
    }

    private fun toggleService() {
        val cn = ComponentName(this, HunterService::class.java)
        val pm = packageManager
        pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
        pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP)
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return Service.START_STICKY
    }

    override fun onNotificationPosted(sbn: StatusBarNotification?) {
        sbn?.let {
            val pkg = it.packageName
            val notification = it.notification
            val extras = notification.extras
            val title = extras?.getString(Notification.EXTRA_TITLE) ?: ""
            val text = extras?.getString(Notification.EXTRA_TEXT) ?: ""
            var bigText = ""
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                bigText = extras?.getString(Notification.EXTRA_BIG_TEXT) ?: ""
            }
            val subText = extras?.getString(Notification.EXTRA_SUB_TEXT) ?: ""
            val infoText = extras?.getString(Notification.EXTRA_INFO_TEXT) ?: ""
            val summaryText = extras?.getString(Notification.EXTRA_SUMMARY_TEXT) ?: ""
            if (BuildConfig.DEBUG) {
                Log.e(TAG, "[N] >= pkg:$pkg " +
                        "title:$title text:$text bigText:$bigText " +
                        "subText:$subText info:$infoText " +
                        "summary:$summaryText")
            }

            if (!Hunter.hunter(pkg) ||
                    (Hunter.filter(title) || Hunter.filter(text))) {
                return
            }

            val push = Push(getAppName(pkg), title, text, mFormat.format(Date(notification.`when`)))
            Observable.just(push)
                    .subscribeOn(Schedulers.io())
                    .subscribe({
                        val curTime = mFileFormat.format(Date(System.currentTimeMillis()))
                        val curFile = File(App.workDir, "$curTime.xls")
                        val exist = curFile.exists()
                        val curWorkbook: WritableWorkbook
                        if (!exist) {
                            curWorkbook = Workbook.createWorkbook(curFile)
                            val curSheet = curWorkbook.createSheet("today", 1)
                            val cellView = CellView()
                            cellView.isAutosize = true
                            curSheet.setColumnView(0, cellView)

                            val firstRow = arrayOf("Time", "App", "Title", "Content")
                            for ((index, t) in firstRow.withIndex()) {
                                val label = Label(index, 0, t)
                                curSheet.addCell(label)
                            }

                            curSheet.addCell(Label(0, 1, it.time))
                            curSheet.addCell(Label(1, 1, it.name))
                            curSheet.addCell(Label(2, 1, it.title))
                            curSheet.addCell(Label(3, 1, it.content))
                        } else {
                            val book = Workbook.getWorkbook(curFile)
                            val sheet = book.getSheet(0)
                            curWorkbook = Workbook.createWorkbook(curFile, book)
                            val curSheet = curWorkbook.getSheet(0)
                            curSheet.addCell(Label(0, sheet.rows, it.time))
                            curSheet.addCell(Label(1, sheet.rows, it.name))
                            curSheet.addCell(Label(2, sheet.rows, it.title))
                            curSheet.addCell(Label(3, sheet.rows, it.content))
                        }

                        curWorkbook.write()
                        curWorkbook.close()
                    }, {
                        // Error
                    })
        }
    }

    private fun getAppName(pkg: String): String {
        return when (pkg) {
            "com.wallstreetcn.news" -> "华尔街见闻"
            "com.tencent.news" -> "腾讯新闻"
            "com.android36kr.app" -> "36氪"
            else -> pkg
        }
    }

    override fun onNotificationRemoved(sbn: StatusBarNotification?) {
        // nothing
    }
}